package bold.deposit.aop;

import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 日志统一拦截
 *
 */
@Log4j2
@Aspect
@Component
@Order(1)
public class LogAspect {

    /**
     * 定义一个方法, 用于声明切入点表达式. 一般地, 该方法中再不需要添入其他的代码.
     * 使用 @Pointcut 来声明切入点表达式.
     * 后面的其他通知直接使用方法名来引用当前的切入点表达式.
     */
    @Pointcut("execution(* bold.deposit.*Controller.*(..))")
    public void range() {
    }

    /**
     * 每一个实现类的每一个方法开始之前执行一段代码
     */
    @Before("range()")
    public void beforeMethod(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        String typeName = joinPoint.getSignature().getDeclaringTypeName();
        Object[] args = joinPoint.getArgs();
        /* log.debug("The method " + methodName + " begins with " + Arrays.asList(args));*/
    }

    /**
     * 在方法执行之后执行的代码. 无论该方法是否出现异常
     */
    @After("range()")
    public void afterMethod(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        /*log.debug("The method " + methodName + " ends");*/
    }

    /**
     * 在方法法正常结束受执行的代码
     * 返回通知是可以访问到方法的返回值的!
     */
    @AfterReturning(value = "range()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        String methodName = joinPoint.getSignature().getName();
        /* log.debug("The method " + methodName + " ends with " + result);*/
    }

    /**
     * 在目标方法出现异常时会执行的代码.
     * 可以访问到异常对象; 且可以指定在出现特定异常时在执行通知代码
     */
    @AfterThrowing(value = "range()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Exception e) {
        String methodName = joinPoint.getSignature().getName();
        /*log.debug("The method " + methodName + " occurs excetion:" + e);*/
    }

}
